package com.futvan.z.system.zfile;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import com.futvan.z.framework.common.bean.Code;
import com.futvan.z.framework.common.bean.Result;
import com.futvan.z.framework.core.SuperAction;
import com.futvan.z.framework.core.z;
import com.futvan.z.framework.util.DateUtil;
import com.futvan.z.framework.util.FileUtil;
import com.futvan.z.framework.util.ImgUtil;
import com.futvan.z.framework.util.JsonUtil;
import com.futvan.z.framework.util.StringUtil;
import com.futvan.z.framework.util.SystemUtil;
import com.futvan.z.system.zfile.ZfileService;
import com.futvan.z.system.zform.z_form_table;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
@Controller
public class ZfileAction extends SuperAction{
	@Autowired
	private ZfileService zfileService;
	private List<File> filelist;

	/**
	 * 创建文件夹
	 * @param dirname 文件夹名称
	 * @return
	 */
	@RequestMapping(value="/CreateServerDir")
	public @ResponseBody Result CreateServerDir(String dirname,String directory){
		Result result = new Result();
		if(z.isNotNull(dirname)) { 
			String dir = getFileSavePath() + "/"+ StringUtil.UrlDecode(directory)+"/"+dirname;
			String rdir = FileUtil.mkdirs(dir);
			File rf = new File(rdir);
			if(z.isNotNull(rf) && rf.isDirectory()) {
				result.setCode(Code.SUCCESS);
				result.setMsg("创建成功");
			}else {
				result.setCode(Code.ERROR);
				result.setMsg("创建失败");
			}
		}else {
			result.setCode(Code.ERROR);
			result.setMsg("文件夹名不可为空");
		}
		return result;
	}

	/**
	 * 服务器文件重命名
	 * @param dirname
	 * @return
	 */
	@RequestMapping(value="/UpdateServerFileName")
	public @ResponseBody Result UpdateServerFileName(String rfilename,String filepath){
		Result result = new Result();
		if(z.isNotNull(rfilename)) { 
			filepath = StringUtil.UrlDecode(filepath);
			if(z.isNotNull(filepath)) { 
				File f = new File(filepath);
				if(z.isNotNull(f)) {
					boolean isok = FileUtil.RenameFileName(f.getAbsolutePath(), rfilename);
					if(isok) {
						result.setCode(Code.SUCCESS);
						result.setMsg("重命名成功");
					}else {
						result.setCode(Code.ERROR);
						result.setMsg("重命名出错");
					}

				}else {
					result.setCode(Code.ERROR);
					result.setMsg("目标文件未找到："+f.getAbsolutePath());
				}
			}else {
				result.setCode(Code.ERROR);
				result.setMsg("目标文件未找到："+filepath);
			}
		}else {
			result.setCode(Code.ERROR);
			result.setMsg("文件名不可为空");
		}
		return result;
	}

	/**
	 * 下载服务器文件
	 * @param rfilename
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/downloadServerFiles")
	public ResponseEntity<byte[]> downloadServerFiles(@RequestParam HashMap<String,String> bean) throws Exception{
		String zids = bean.get("zids");
		String directory = bean.get("directory");
		
		if(z.isNotNull(zids)) { 
			//创建文件头信息
			
			HttpHeaders headers = new HttpHeaders();
			String zipname = "z"+DateUtil.getDateTime("yyyyMMddHHmm")+".zip";
			headers.setContentDispositionFormData("attachment", zipname);
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			String dir = request.getServletContext().getRealPath("/")+"temp/";
			FileUtil.mkdirs(dir);
			byte[] file = ZipDownloadServerFiles(zids,dir+zipname);
			
			//删除临时文件
			File zipname_temp = new File(dir+zipname);
			if(z.isNotNull(zipname_temp) && zipname_temp.isFile()) {
				zipname_temp.delete();
			}
			
			return new ResponseEntity<byte[]>(file,headers, HttpStatus.CREATED);

		}else {
			z.Exception("请选择要下载的文件");
			return null;
		}
	}


	/**
	 * 压缩下载文件
	 * @param zids
	 * @param directory 
	 * @return
	 * @throws Exception 
	 */
	private byte[] ZipDownloadServerFiles(String zids, String dir) throws Exception {
		ZipFile zipFile = new ZipFile(dir);
		String [] zidarray = zids.split(",");
		List<File> listfile = new ArrayList<File>();
		for (String zid : zidarray) {
			File f = new File(StringUtil.UrlDecode(zid));
			if(f.isDirectory()) {
				zipFile.addFolder(f);
			}else {
				zipFile.addFile(f);
			}
		}
		
		File rfile = new File(dir);
		if(z.isNotNull(rfile) && rfile.isFile()) {
			return FileUtil.getBytes(rfile);
		}else {
			return null;
		}
	}

	/**
	 * 获取所有本地文件
	 * @param bean
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/all_file_list")
	public ModelAndView all_file_list(String directory) {
		ModelAndView mv = new ModelAndView("system/zfile/all_file_list");
		//获取当前目录所有文件
		mv.addObject("filelist", getFiles(StringUtil.UrlDecode(directory)));

		//获取当前目录到根目录的所有目录集
		List<z_file> pathlist = new ArrayList<z_file>();
		getPathList(StringUtil.UrlDecode(directory),pathlist);
		Collections.reverse(pathlist);//倒序
		mv.addObject("pathlist", pathlist);

		//当前目录
		mv.addObject("directory", StringUtil.UrlEncode(directory));



		return mv;
	}

	/**
	 * 获取路径集合，根据当前目录向上找。直到找到根目录
	 * @param urlDecode
	 * @return
	 */
	private void getPathList(String directory,List<z_file> pathlist) {
		String default_root_path = getFileSavePath();
		if(z.isNotNull(directory)) {
			//如果第一位不是/，就补充一个/
			if(!"/".equals(directory.substring(0, 1))) {
				directory = "/"+directory;
			}
			File directoryFile = new File(default_root_path+directory);
			z_file zf = new z_file();
			zf.setZid(StringUtil.jia_old(directoryFile.getPath().replace("\\", "☆")));
			zf.setName(directoryFile.getName());
			zf.setFilepath(StringUtil.UrlEncode(directory));
			pathlist.add(zf);

			//判读当前目录的上级目录是不是根目录，如果不是，找到上级目录
			if(!directoryFile.getParent().equals(default_root_path)) {
				File ParentdirectoryFile = new File(directoryFile.getParent());
				getPathList(ParentdirectoryFile.getName(),pathlist);
			}
		}
	}

	//获取文件列表
	private List<z_file> getFiles(String path) {
		List<z_file> list = new ArrayList<z_file>();
		File root = null;
		String default_root_path = getFileSavePath();
		FileUtil.mkdirs(default_root_path);
		//设置访问目录
		if(z.isNull(path)) {
			root = new File(default_root_path);
		}else {
			//如果第一位不是/，就补充一个/
			if(!"/".equals(path.substring(0, 1))) {
				path = "/"+path;
			}
			root = new File(default_root_path+path);
			if(root.exists()) {
				if(!root.isDirectory()) {
					root = new File(default_root_path);
				}
			}else {
				root = new File(default_root_path);
			}
		}
		//获取目录下所有文件
		File[] files = root.listFiles();
		//遍历所有文件
		for (File f : files) {
			z_file zf = new z_file();
			//设置主键
			zf.setZid(StringUtil.UrlEncode(f.getPath()));
			//文件名称
			zf.setName(f.getName());
			//文件类型
			String filetype = "";
			if(f.isDirectory()) {
				filetype = "目录";
			}else {
				if(f.getName().lastIndexOf(".")>0) {
					filetype = f.getName().substring(f.getName().lastIndexOf(".")+1).toUpperCase();
				}else {
					filetype = "无类型文件";
				}
			}
			zf.setFile_type(filetype);
			//创建时间
			zf.setCreate_time(DateUtil.FormatDate(new Date(f.lastModified()), "yyyy-MM-dd HH:mm:ss"));
			//设置文件大小
			zf.setSize(FileUtil.CalculateFileSize(f));
			//WEB访问地址
			String url = "";
			if(f.isDirectory()) {
				url = f.getPath().replace(default_root_path, "").replace("\\", "/");
			}else {
				url = z.getWebURL()+"/files"+f.getPath().replace(default_root_path, "").replace("\\", "/");
			}
			zf.setFilepath(url);

			//保存到返回集合
			list.add(zf);
		}
		Collections.sort(list,new Comparator<z_file>() {
			public int compare(z_file o1, z_file o2) {
				return o2.getFile_type().compareTo(o1.getFile_type());
			}
		});
		return list;
	}

	/**
	 * 删除文件
	 * @param zid
	 * @return
	 */
	@RequestMapping(value="/deleteLocalFile",method=RequestMethod.GET)
	public @ResponseBody Result deleteLocalFile(String zids){
		Result result = new Result();
		if(z.isNotNull(zids)) { 
			String [] zidarray = zids.split(",");
			StringBuffer info = new StringBuffer();
			for(int i=0;i<zidarray.length;i++) {
				String zid = zidarray[i];
				String zfilepath = StringUtil.UrlDecode(zid);
				File file = new File(zfilepath);
				if(file.exists() && (file.isFile()|| file.isDirectory() )) {
					boolean isDelete = FileUtil.deletes(file);
					if(isDelete) {
						info.append("成功删除文件："+file.getName()).append("\r\n");
					}else {
						info.append("删除文件不成功："+file.getName()).append("\r\n");
					}
				}else {
					info.append("未找到文件："+file.getName()).append("\r\n");
				}
			}
			result.setCode(Code.SUCCESS);
			result.setMsg(info.toString());
		}else {
			result.setCode(Code.ERROR);
			result.setMsg("zids is null");
		}
		return result;
	}


	/**
	 * 
	 * @return
	 * @throws Exception
	 */
	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value="/upload")
	public @ResponseBody Result upload(String filepath,HttpServletRequest request){
		Result result = new Result();
		String fileReturnPath = "";
		List<String> uploadFileList = new ArrayList<String>();
		try {
			//将当前上下文初始化给  CommonsMutipartResolver （多部分解析器）
			CommonsMultipartResolver multipartResolver=new CommonsMultipartResolver(request.getSession().getServletContext());
			//检查form中是否有enctype="multipart/form-data"
			if(multipartResolver.isMultipart(request)){
				//将request变成多部分request
				MultipartHttpServletRequest multiRequest=(MultipartHttpServletRequest)request;
				//获取multiRequest 中所有的文件名
				Iterator iter=multiRequest.getFileNames();
				while(iter.hasNext()){
					//一次遍历所有文件
					MultipartFile file=multiRequest.getFile(iter.next().toString());
					if(file!=null){
						//创建保存路径
						String fileSavePath = CreateFileSavePath(filepath);

						//保存文件
						String filename = StringUtil.UrlDecode(file.getOriginalFilename());
						save(file,fileSavePath+"/"+ filename);

						//创建返回URL
						fileReturnPath = z.sp.get("fileserverurl")+"/files/"+filepath+"/"+filename;
						uploadFileList.add(fileReturnPath);

						//如果是图片，返回压缩图片路径
						//						if(ImgUtil.isImg(file.getOriginalFilename())) {
						//							String z1_fileReturnPath = z.sp.get("fileserverurl")+"/files/"+filepath+"/"+ file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")) +"_z1." + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1); 
						//							uploadFileList.add(z1_fileReturnPath);
						//							
						//							String z5_fileReturnPath = z.sp.get("fileserverurl")+"/files/"+filepath+"/"+ file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf(".")) +"_z5." + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1); 
						//							uploadFileList.add(z5_fileReturnPath);
						//						}


						//保存文件名到数据库
						zfileService.save(fileReturnPath,filepath,z.sp.get("fileserverurl"),filename);
					}
				}
			}
			result.setCode(Code.SUCCESS);
			result.setMsg("上传成功");
			result.setData(fileReturnPath);
		} catch (Exception e) {
			result.setCode(Code.ERROR);
			result.setMsg("file upload error："+e.getMessage());
			result.setData(e.getMessage());
		} 
		return result;
	}
	
	
	@RequestMapping(value="/upload_imgdate")
	public @ResponseBody Result upload_imgdate(@RequestParam HashMap<String,String> bean) throws Exception{
		Result result = new Result();
		String imgdate = bean.get("imgdate");
		String ColumnId = bean.get("ColumnId");
		String PageType = bean.get("PageType");
		String zid = bean.get("zid");
		String tableId = bean.get("tableId");
		
		if(z.isNotNull(tableId)){
			if(z.isNotNull(zid)){
				if(z.isNotNull(PageType)){
					if(z.isNotNull(ColumnId)){
						if(z.isNotNull(imgdate)){
							String name = z.newNumber()+".jpg";
							
							//创建保存路径
							String fileSavePath = CreateFileSavePath("img");

							//转义还原
							imgdate = StringUtil.UrlDecode(imgdate);
							
							//保存文件
							ImgUtil.Base64ToImg(fileSavePath+"/"+name,imgdate);
							
							//创建返回URL
							String fileReturnPath = z.sp.get("fileserverurl")+fileSavePath.replace(System.getProperty(z.sp.get("webAppRootKeyValue")), "")+"/"+name;
							
							//如果是list直接保存URL到数据库
							if("list".equals(PageType)) {
								int num = sqlSession.update("update", "update "+tableId+" set "+ColumnId+" ='"+fileReturnPath+"' where zid = '"+zid+"'");
								if(num!=1) {
									z.Exception("图片字段拍照上传出错，保存URL到数据库出错|update not 1");
								}
							}
							result.setCode(Code.SUCCESS);
							result.setMsg("上传成功");
							result.setData(fileReturnPath);
						}else {
							result.setCode(Code.ERROR);
							result.setMsg("imgdate is null");
						}
					}else {
						result.setCode(Code.ERROR);
						result.setMsg("ColumnId is null");
					}
				}else {
					result.setCode(Code.ERROR);
					result.setMsg("PageType is null");
				}
			}else {
				result.setCode(Code.ERROR);
				result.setMsg("zid is null");
			}
		}else {
			result.setCode(Code.ERROR);
			result.setMsg("tableId is null");
		}
		return result;
	}

	private String CreateFileSavePath(String filepath) throws Exception{
		String fileSavePath = "";
		String project_path = System.getProperty(z.sp.get("webAppRootKeyValue"));
		if(!"".equals(project_path) && project_path!=null) {
			fileSavePath = project_path;
			//判读路径是否为空
			if(!"".equals(filepath) && filepath!=null) {
				fileSavePath = fileSavePath+"/files/"+filepath;
			}else {
				fileSavePath = fileSavePath+"/files";
			}

			// 判断文件目录是否存在如果不存在怎么创建
			File dir = new File(fileSavePath);
			if (!dir.exists() && !dir.isDirectory()) {
				//创建多级目录
				dir.mkdirs();
			}
		}else {
			throw new Exception("文件服务器系统错误:创建文件保存路径出错。请稍后上传。");
		}
		return fileSavePath;
	}

	/**
	 * 保存文件
	 * @throws Exception
	 */
	private void save(MultipartFile file,String fileSavePath) throws Exception{
		file.transferTo(new File(fileSavePath));

		//同时生成压缩文件
		//ImgUtil.ImgZip(fileSavePath);
	}
}
